import Konva from "konva";
import { Draw } from "./Draw";
import { isPreview } from "../Utils";
import { PreviewMode } from "../Enumerate/PreviewMode";

/**
 *  预览相关实现类：
 *   1. 记录 currentIndex
 *   2. 实现预览功能
 */
export class PreviewManager {
  private draw: Draw;
  private mode = PreviewMode.beginning; // 默认从头开始预览
  // 要维护自己的预览index
  private previewIndex = 0;
  private previewLayerList: Konva.Layer[] = [];
  private previewStage: Konva.Stage | null = null;

  constructor(draw: Draw) {
    this.draw = draw;
  }

  /** 预览实现 */
  public preview(mode?: PreviewMode, index?: number) {
    const layer = this.draw.getLayer();
    // 如果处于预览状态下，则不做任何处理
    if (!layer || isPreview()) return;
    // 如果mode存在，则更新mode
    if (mode) this.mode = mode;
    if (index) this.previewIndex = index;
    // 创建容器
    const previewBox = document.createElement("div");
    previewBox.className = "konva-root-preview";
    document.querySelector("body")?.appendChild(previewBox);
    const previewContainer = document.createElement("div");
    previewBox.appendChild(previewContainer);
    // 进入全屏
    previewBox.requestFullscreen();
  }

  /** 监听全屏事件 */
  public fullscreenchange() {
    // 监听全屏事件
    const previewBoxSelector = ".konva-root-preview > div";
    type HDE = HTMLDivElement;
    const previewBox = <HDE>document.querySelector(previewBoxSelector);
    const konvaGraph = this.draw.getKonvaGraph();

    // 如果处于全屏状态，并且全屏元素存在，才能执行预览操作
    if (document.fullscreenElement && previewBox) {
      const { innerWidth, innerHeight } = window; // 全屏后最佳的预览尺寸

      // 计算编辑区的stage宽高
      const drawStage = this.draw.getStage();
      const drawWidth = drawStage.width();
      const drawHeight = drawStage.height();

      // 计算缩放比例
      const scaleX = innerWidth / drawWidth;
      const scaleY = innerHeight / drawHeight;
      const scale = Math.min(scaleX, scaleY);

      // 被预览元素与全屏最优尺寸一致
      const width = scale * drawWidth;
      const height = scale * drawHeight;
      previewBox.style.width = width + "px";
      previewBox.style.height = height + "px";

      // 创建新的 stage
      const stageOptions = { container: previewBox, width, height };
      this.previewStage = new Konva.Stage(stageOptions);
      // 预览状态下，仅有 stage 能接受事件
      this.previewStage.on("click", () => this.previewStageClick.call(this));

      // 预览模式下，元素是不可拖拽，缩放的！
      this.previewLayerList = [];
      const layerList = this.draw.getLayerManager().getLayerList();
      (layerList || []).forEach((layer) => {
        const layerClone = layer.clone();
        // 取消网格线 - 不删背景ha
        const bgGroup = <Konva.Group>layerClone.findOne(".bgGroup");
        bgGroup?.findOne(".bgLineGroup")?.destroy();
        // 取消形变
        layerClone.find("Transformer").forEach((tr) => tr.destroy());
        // 循环每一个 group - 取消事件
        layerClone.children.forEach((group) => {
          // 取消节点的 animationTag
          konvaGraph.removeAnimationTag(<Konva.Group>group);
          group.setAttr("draggable", null);
          group.off("click");
          group.off("dragmove");
          group.off("dragend");
          group.off("mouseenter");
          group.off("mouseleave");
          group.off("dblclick");
        });
        this.previewLayerList.push(layerClone.scale({ x: scale, y: scale })); // 为了达到最佳预览的效果，应该进行合理的缩放
      });

      // 如果没有幻灯片，则提示最后一张
      this.addEndSlide(width, height);

      if (this.mode === PreviewMode.beginning) {
        // 至于应该初始化第几个幻灯片，是由 mode 决定的
        this.previewStage.add(this.previewLayerList[0]);
        this.previewIndex = 0;
      } else if (this.mode === PreviewMode.current) {
        const index = this.draw.getLayerManager().getCurrentIndex()!;
        this.previewIndex = index;
        this.previewStage.add(this.previewLayerList[index]);
      } else if (this.mode === PreviewMode.index) {
        const index = this.previewIndex;
        this.previewStage.add(this.previewLayerList[index]);
      }
    } else {
      // 退出全屏后，删除元素
      (<HTMLDivElement>previewBox.parentNode)?.remove();
      // 恢复默认预览模式
      this.mode = PreviewMode.beginning;
      this.previewIndex = 0;
      this.previewStage = null;
      this.previewLayerList = [];
    }
  }

  public addEndSlide(width: number, height: number) {
    // 需要添加放映结束标识
    const endLayer = new Konva.Layer({ fill: "#000" });
    endLayer.add(
      new Konva.Text({
        text: "放映结束",
        fontSize: 30,
        fontFamily: "Calibri",
        fill: "white",
        align: "center",
        verticalAlign: "middle",
        width,
        height,
      })
    );
    this.previewLayerList.push(endLayer);
  }

  /**
   * 预览舞台点击事件处理函数 - 这里的点击有几点需要考虑的：
   *  1. 如何实现动画播放
   *  2. 如何实现上下页面切换（不考虑动画的reverse，直接回退上一个幻灯片）
   */
  public previewStageClick(direction?: "up" | "down") {
    // 每点击一次，都需要判断是否有元素动画需要执行，如果没有则切换下一个幻灯片
    if (!this.previewStage) return;
    // this.previewStage.getLayers()!.forEach((layer) => layer.destroy());

    // const konvaAnimation = this.draw.getAnimation().konva;
    // 上一个幻灯片
    if (direction === "up") {
      // const prevLayer = this.previewLayerList[this.previewIndex - 1];
      // this.previewIndex--;
    } else {
      // 判断当前图层是否存在动画节点
      // const currentLayer = this.previewLayerList[this.previewIndex];
      // const animationList = konvaAnimation.getAnimationList(currentLayer);
      // console.log(animationList);
      // // 是否结束放映
      // if (this.previewIndex === this.previewLayerList.length - 1) {
      //   // 退出全屏
      //   return document.exitFullscreen();
      // }

      // // 没有 则跳到下一个幻灯片
      // const nextLayer = this.previewLayerList[this.previewIndex + 1];
      // if (nextLayer) {
      //   this.previewStage.add(nextLayer);
      // }

      // this.previewIndex++;
    }
  }
}
